/**
 * 2017年7月23日
 */
package compiler.antlr;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URISyntaxException;
import java.util.Arrays;

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.TokenStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Alex
 *
 */
// java -cp 
public class Tool {
	static Logger logger  = LoggerFactory.getLogger(Tool.class);
	/**
	 * 第一个参数请输入全限定包名加上*.g4文件名,这个文件名读取的是源码文件中的
	 * 程序在g4文件所在的包中生成词法分析器(Lexer)及解析器(Parser)
	 * 例如:
	 * compiler/antlr/helloworld/Alex.g4
	 * @param args
	 * @throws URISyntaxException
	 */
	public static void main(String[] args) throws URISyntaxException {
		String projectDir = System.getProperty("user.dir");
		File mavenSrc = new File(projectDir,"src/main/java");
		if(args.length == 0) return ;
		//args 包含*.g4文件名即可
		File f = new File(args[0]);
		String nameWithoutExt = f.getName().substring(0,f.getName().lastIndexOf('.'));
		logger.info("FileName without Ext:{}",nameWithoutExt);
		String packageName = args[0].substring(0, args[0].lastIndexOf('/')).replace("/", ".");
		logger.info("PackageName:{}",packageName);
		File target = new File(mavenSrc,args[0]);
		String insertLine = "package "+packageName+";//";
		Runtime.getRuntime().addShutdownHook(new Thread(()->{
			File javaDir = target.getParentFile();
			String javas[] = javaDir.list((dir,name)->name.endsWith("java") && name.startsWith(nameWithoutExt));
			Arrays.asList(javas).stream().forEach(x->{
				try {
					try(RandomAccessFile javaFile = new RandomAccessFile(new File(javaDir,x),"rw")){
						javaFile.seek(0);
						javaFile.write(insertLine.getBytes());
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			});
		}));
		org.antlr.v4.Tool.main(new String[]{target.getAbsolutePath()});
		
	}
	public static void main2(String[] args) throws Exception {
		args = new String[]{args[0],
				args[1],
				new File(Tool.class.getClassLoader().getResource(args[2]).toURI()).getAbsolutePath(),
				"-r",
				"-gui"
				};
		org.antlr.v4.gui.TestRig.main(args);
	}
	public static <P extends Parser> P getParser(String name,Class<? extends Lexer> lex,Class<P> parser) throws IOException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		CharStream cs = new ANTLRInputStream(Tool.class.getClassLoader().getResourceAsStream(name));
		Constructor<?> lexc = lex.getDeclaredConstructor(CharStream.class);
		Lexer lexObj = (Lexer) lexc.newInstance(cs);
		CommonTokenStream ts = new CommonTokenStream(lexObj);
		Constructor<P> c = parser.getDeclaredConstructor(TokenStream.class);
		return c.newInstance(ts);

	}
}
